package com.myk.game.gobangchess.ai.gravityfour;

public class KillJudging {

    public static int[] killJudgingDeep1(int[][] board) {
        int[] iskill = new int[2];
        int[][][] convKernels = {{{1, 0, 0, 0},
                                  {0, 1, 0, 0},
                                  {0, 0, 1, 0},
                                  {0, 0, 0, 1}},
                                 {{1, 1, 1, 1}}};

        int[][] convResult = conv2(board, convKernels[0]);
        iskill = checkConvResult0(convResult, iskill);

        board = rotateMatrix(board);
        convResult = conv2(board, convKernels[0]);
        iskill = checkConvResult0(convResult, iskill);

        convResult = conv2(board, convKernels[1]);
        iskill = checkConvResult1(convResult, iskill);

        board = rotateMatrix(board);
        convResult = conv2(board, convKernels[1]);
        iskill = checkConvResult1(convResult, iskill);

        return iskill;
    }

    public static int[][] conv2(int[][] matrix1, int[][] matrix2) {
        int m = matrix1.length;
        int n = matrix1[0].length;
        int p = matrix2.length;
        int q = matrix2[0].length;
        int r = m - p + 1;
        int s = n - q + 1;
        
        int[][] result = new int[r][s];

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < s; j++) {
                for (int k = 0; k < p; k++) {
                    for (int l = 0; l < q; l++) {
                        result[i][j] += matrix1[i + k][j + l] * matrix2[k][l];
                    }
                }
            }
        }

        return result;
    }

    private static int[][] rotateMatrix(int[][] matrix) {
        int size = matrix.length;
        int[][] result = new int[size][size];

        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                result[i][j] = matrix[size - j - 1][i];
            }
        }
        return result;
    }

    private static int[] checkConvResult0(int[][] convResult, int[] iskill) {
        for (int i = 0; i < convResult.length; i++) {
            for (int j = 0; j < convResult[0].length; j++) {
                if (convResult[i][j] == 4) {
                    if (i > 0 && i < convResult.length - 1 && j > 0 && j < convResult[0].length - 1) {
                        if (convResult[i + 1][j + 1] != 4 && convResult[i - 1][j - 1] != 4) {
                            iskill[0] = 1;
                        }
                    } else if((i == 0||j == 0) && i < convResult.length - 1 && j < convResult[0].length - 1 && convResult[i + 1][j + 1] != 4){
                        iskill[0] = 1; 
                    } else if((i == convResult.length - 1||j == convResult[0].length - 1) && i > 0 && j > 0 && convResult[i - 1][j - 1] != 4){
                        iskill[0] = 1;
                    } else if((i == convResult.length - 1&&j == 0) || (i == 0&&j == convResult[0].length - 1)){
                        iskill[0] = 1;
                    }
                } else if (convResult[i][j] == -4) {
                    if (i > 0 && i < convResult.length - 1 && j > 0 && j < convResult[0].length - 1) {
                        if (convResult[i + 1][j + 1] != -4 && convResult[i - 1][j - 1] != -4) {
                            iskill[1] = 1;
                        }
                    } else if((i == 0||j == 0) && i < convResult.length - 1 && j < convResult[0].length - 1 && convResult[i + 1][j + 1] != -4){
                        iskill[1] = 1; 
                    } else if((i == convResult.length - 1||j == convResult[0].length - 1) && i > 0 && j > 0 && convResult[i - 1][j - 1] != -4){
                        iskill[1] = 1;
                    } else if((i == convResult.length - 1&&j == 0) || (i == 0&&j == convResult[0].length - 1)){
                        iskill[1] = 1;
                    }
                }
            }
        }
        return iskill;
    }

    private static int[] checkConvResult1(int[][] convResult, int[] iskill) {
        for (int i = 0; i < convResult.length; i++) {
            for (int j = 0; j < convResult[0].length; j++) {
                if (convResult[i][j] == 4) {
                    if (j > 0 && j < convResult[0].length - 1) {
                        if (convResult[i][j-1] != 4 && convResult[i][j+1] != 4) {
                            iskill[0] = 1;
                        }
                    } else if(j == 0 && convResult[i][j+1] != 4){
                        iskill[0] = 1; 
                    } else if(j == convResult[0].length - 1&& convResult[i][j-1] != 4){
                        iskill[0] = 1;
                    }
                } else if (convResult[i][j] == -4) {
                    if (j > 0 && j < convResult[0].length - 1) {
                        if (convResult[i][j-1] != -4 && convResult[i][j+1] != -4) {
                            iskill[1] = 1;
                        }
                    } else if(j == 0 && convResult[i][j+1] != -4){
                        iskill[1] = 1; 
                    } else if(j == convResult[0].length - 1&& convResult[i][j-1] != -4){
                        iskill[1] = 1;
                    }
                }
            }
        }
        return iskill;
    }

}
